//
// Created by tongj on 2023/10/6.
//

#ifndef TBS_CPP_MESSAGE_H
#define TBS_CPP_MESSAGE_H

#include <base/base.hpp>
#include <base/buffer.h>

namespace MessageQueue {

class MsgQueue;

class IConsumable {
public:
  using consume_listenner = std::function<void(CONST IConsumable &)>;
  enum StatusEnum {
	/**
	 * 已消费
	 */
	Consumed,   /**
                         * 未消费
                         */
	UnConsumed, /**
                         * 重试
                         */
	Retry,      /**
                         * 丢弃
                         */
	Drop
  };

  /**
   * 获取当前状态
   * @return
   */
  StatusEnum status() CONST;

  /**
   * 消费
   * @return 消费结果状态
   */
  StatusEnum consume();

  DESTRUCTION(IConsumable)

protected:
  /**
   * 自定义消费函数
   * @return
   */
  virtual StatusEnum _consume() = 0;

  /**
   * 消费后置监听
   * @return
   */

  virtual consume_listenner _listener();

private:
  /**
   * 设置状态
   * @param statusEnum
   */
  void setStatus(CR(StatusEnum, statusEnum));

  StatusEnum _status = UnConsumed;
};

class IIndexable {
protected:
  /**
   * 顺序
   * @return
   */
  virtual tbs::u_size _index() CONST = 0;

public:
  bool operator<(CONST IIndexable &oth) CONST {
	return _index() > oth._index();
  }
};

class DelayMessage : public virtual tbs::buffer::Buffer, public virtual IConsumable, public virtual IIndexable {

public:
  using _consumeMethod = std::function<StatusEnum(DelayMessage & )>;

  explicit DelayMessage(_consumeMethod method = nullptr);

  /**
   * 设置延时，时间单位为standrad_time
   * @param t
   */

  void setTime(long long t);

  /**
   * 获取延时
   * @return
   */
  long long getTime() CONST;

  /**
   * 获取投送的消息队列
   * @return
   */
  MsgQueue *owner() CONST;

  /**
   * 设置消费监听器
   * @param consumeListenner
   * @return
   */
  DelayMessage &setConsumeListener(consume_listenner consumeListenner);

  /**
   * 设置消费方法
   * @param method
   * @return
   */
  DelayMessage &setConsumeMethod(_consumeMethod method);

  /**
   * 延时比较器
   * @param left
   * @param right
   * @return
   */
  static bool compare(CONST DelayMessage &left, CONST DelayMessage &right) {
	return left < right;
  }

private:
  long long _time;
  _consumeMethod _method;
  IConsumable::consume_listenner _m_listener;
  MsgQueue *_owner = nullptr;
  friend MsgQueue;

protected:
  StatusEnum _consume() override;

  consume_listenner _listener() override;

  tbs::u_size _index() CONST override;
};

}

#endif // TBS_CPP_MESSAGE_H
